package br.com.foxinline.manager.criar;

import br.com.foxinline.modelo.Anexo;
import br.com.foxinline.servico.AnexoServico;
import br.com.foxinline.servico.ImovelServico;
import br.com.foxinline.util.ArquivoUtilitario;
import br.com.foxinline.util.Msg;
import java.io.*;
import java.util.Iterator;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.annotation.PostConstruct;
import javax.ejb.EJB;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import javax.imageio.ImageIO;
import javax.imageio.ImageReader;
import javax.imageio.stream.FileImageInputStream;
import javax.imageio.stream.ImageInputStream;
import javax.servlet.http.HttpServletRequest;

/**
 *
 * @author laverson
 */
@ManagedBean
@ViewScoped
public class ManagerImagem implements Serializable {

    @EJB
    ImovelServico imovelServico;
    @EJB
    AnexoServico anexoServico;
    private ArquivoUtilitario arquivoUtilitario;
    private static final String URL_IMAGENS = "imagens/";
    private static final String URL_PREVISUALIZAR = "previsualizar/";
    private static final String URL_PDF = "media/images/pdf.jpeg";
    private static final String THUMBNAIL = "thumbnail.";
    private static final String APPLICATION_PDF = "application/pdf";
    private static final String APPLICATION_NAME = "Atlas-war/";
    private static final int tamanhoMaximoNome = 10;
    private String URL;
    //Restaurar Imagem
    private Long idAnexo;

    @PostConstruct
    public void init() {
        URL = getRequestURL();
        String[] split = URL.split(APPLICATION_NAME);
        URL = "show?img=" + split[0].concat(APPLICATION_NAME);
    }

    /**
     * Retorna a URL do sistema
     *
     * @return
     */
    public String getRequestURL() {
        Object request = FacesContext.getCurrentInstance().getExternalContext().getRequest();
        if (request instanceof HttpServletRequest) {
            String requestURL = ((HttpServletRequest) request).getRequestURL().toString();
            return requestURL;
        }
        return URL;
    }

    /**
     * Retorna a URL da miniatura do anexo
     *
     * @param anexo
     * @return "show/?annex=/caminho/thumbnail.imagem.[jpg|png|...]"
     */
    public String urlThumbnailImagem(Anexo anexo) {

        if (anexo != null && anexo.getArquivo() == null && anexo.getId() == null) {

            if (anexo.getNome() != null) {
                return substituirAcentos(anexo.getNome());
            }
        }

        if (anexo != null && anexo.getUrl() != null && !anexo.getUrl().isEmpty()) {

            if (anexo.getNome() == null) {
                return URL;
            }

            String url;

            if (anexo.getId() != null) {
                url = URL_IMAGENS;
                url += anexo.getUrl().replace(ArquivoUtilitario.REAL_PATH_OPT, "") + THUMBNAIL + anexo.getNome();
            } else {
                url = URL_PREVISUALIZAR;
                url += THUMBNAIL + anexo.getNome();
            }

            return substituirAcentos(url);
        }

        return URL;
    }

    /**
     * Retorna a imagem em tamanho normal
     *
     * @param anexo
     * @return
     */
    public String urlImagem(Anexo anexo) {

        if (anexo == null) {
            return URL;
        }

        //@todo Deve ser removido após criar método para excluir arquivos remanecentes na tabela anexo
        if (anexo.getId() != null && anexo.getUrl() != null && (anexo.getContent() != null || anexo.getArquivo() != null)) {
            arquivoUtilitario = new ArquivoUtilitario();
            arquivoUtilitario.gravarAnexo(anexo, anexo.getUrl());
            anexo.setContent(null);
            anexo.setArquivo(null);
            anexoServico.update(anexo);
        }

        if (anexo.getNome() == null) {
            return URL;
        }

        // Se o anexo não estiver salvo retorna a url na pasta TMP
        if (anexo.getId() == null) {
            if (anexo.getUrl() != null && !anexo.getUrl().isEmpty()) {
                return URL_PREVISUALIZAR + substituirAcentos(anexo.getNome());
            }
        }

        if (anexo.getUrl() != null && !anexo.getUrl().isEmpty()) {
            String url = URL_IMAGENS;

            url += anexo.getUrl().replace(ArquivoUtilitario.REAL_PATH_OPT, "") + substituirAcentos(anexo.getNome());

            return url;
        }

        return URL;
    }

    /**
     * Retorna a URL para visualziar a imagem no navegador
     *
     * @param anexo
     * @return "/caminho/imagem.[jpg|png|...]"
     */
    public String urlVisualziarImagem(Anexo anexo) {

        if (anexo != null && anexo.getId() == null) {
            if (anexo.getContent() != null && !anexo.getContent().isEmpty()) {

                return anexo.getContent();
            }

            if (anexo.getUrl() != null && !anexo.getUrl().isEmpty()) {
                return anexo.getUrl() + anexo.getNome();
            }

        } else if (anexo != null && anexo.getId() != null) {

            return anexo.getNome();
        }


        return URL;
    }

    /**
     * Retorna a URL para visualizar a miniatura do PDF
     *
     * @return "assets/images/pdf.jpeg"
     */
    public String getUrlPDF() {
        return URL_PDF;
    }

    public String nomeAnexo(Anexo anexo) {

        if (anexo.getNomeExibicao() != null && !anexo.getNomeExibicao().isEmpty()) {
            if (anexo.getNomeExibicao().length() >= tamanhoMaximoNome) {
                return anexo.getNomeExibicao().substring(0, tamanhoMaximoNome).concat("...");
            }

            return anexo.getNomeExibicao().replace(".png", "").replace(" ", "_");
        }

        if (anexo.getNome() != null && !anexo.getNome().isEmpty() && anexo.getNome().length() >= tamanhoMaximoNome) {
            return anexo.getNome().substring(0, tamanhoMaximoNome).concat("...");
        }

        if (anexo.getNome() != null && !anexo.getNome().isEmpty()) {
            return anexo.getNome().replace(".png", "").replace(" ", "_");
        }

        return "img.png";
    }

    /**
     * Retorna o nome do arquivo truncado se seu tamanho for superior a 10 caracteres
     *
     * @param anexo
     * @return
     */
    public String nomeAnexoPdf(Anexo anexo) {
        if (anexo.getNomeExibicao() != null) {
            if (anexo.getNomeExibicao().length() >= tamanhoMaximoNome) {
                return anexo.getNomeExibicao().substring(0, tamanhoMaximoNome).concat("...");
            }
            return anexo.getNomeExibicao().replace(".pdf", "").replace(" ", "_");
        }

        if (anexo.getNome().length() >= tamanhoMaximoNome) {
            return anexo.getNome().substring(0, tamanhoMaximoNome).concat("...");
        }
        return anexo.getNome().replace(".pdf", "").replace(" ", "_");
    }

    /**
     * Verifica se o arquivo é um PDF
     *
     * @param anexo
     * @return
     */
    public boolean PDF(Anexo anexo) {
        return anexo.getTipo() != null && anexo.getTipo().equals(APPLICATION_PDF);
    }

    /**
     * Verifica se o arquivo é uma imagem
     *
     * @param anexo
     * @return
     */
    public boolean imagem(Anexo anexo) {
        return anexo.getTipo() != null && !anexo.getTipo().equals(APPLICATION_PDF);
    }

    public String widthHeight(Anexo anexo) {
        int width = 1024;
        int height = 1024;

        if (anexo != null && anexo.getUrl() != null && !anexo.getUrl().isEmpty() && anexo.getNome() != null) {
            String suffix = this.getFileSuffix(anexo.getUrl().concat(anexo.getNome()));

            Iterator<ImageReader> iter = ImageIO.getImageReadersBySuffix(suffix);
            if (iter.hasNext()) {
                ImageReader reader = iter.next();
                try {
                    ImageInputStream stream = new FileImageInputStream(new File(anexo.getUrl().concat(anexo.getNome())));
                    reader.setInput(stream);
                    width = reader.getWidth(reader.getMinIndex());
                    height = reader.getHeight(reader.getMinIndex());
                } catch (IOException e) {
                    System.err.println(e);
                } finally {
                    reader.dispose();
                }
            }
        }
        return width + "x" + height;
    }

    public String getFileSuffix(final String path) {
        String result = null;
        if (path != null) {
            result = "";
            if (path.lastIndexOf('.') != -1) {
                result = path.substring(path.lastIndexOf('.'));
                if (result.startsWith(".")) {
                    result = result.substring(1);
                }
            }
        }
        return result;
    }

    private String substituirAcentos(String nome) {
        if (nome != null) {
            return nome.replaceAll("[ãâàáä]", "X").replaceAll("[êèéë]", "X").replaceAll("[îìíï]", "X").replaceAll("[õôòóö]", "X").replaceAll("[ûúùü]", "X").replaceAll("[ÃÂÀÁÄ]", "X").replaceAll("[ÊÈÉË]", "X").replaceAll("[ÎÌÍÏ]", "X").replaceAll("[ÕÔÒÓÖ]", "X").replaceAll("[ÛÙÚÜ]", "X").replace('ç', '?').replace('Ç', '?').replace("[ñǹń]", "X").replace("[ÑŃǸ]", "X");
        }

        return "";
    }

    public void edit() {
        Map<String, String> params = FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap();
        Long idAnexo = null;
        if (params.get("imageForm:pid") != null) {
            try {
                String param = params.get("imageForm:pid");
                if (!param.equals("null")) {
                    idAnexo = Long.parseLong(param);
                    ExternalContext context = FacesContext.getCurrentInstance().getExternalContext();
                    context.redirect("viewImage.xhtml?anexo=" + idAnexo);
                } else {
                    Msg.messagemWarn("Salve o anexo antes de editar!");
                }
            } catch (IOException ex) {
                Logger.getLogger(ManagerImagem.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }

    public void restaurarAnexo(Anexo a) {
        ArquivoUtilitario au = new ArquivoUtilitario();
        String nomeOriginal = a.getNome().replace("copia_", "");
        File fileOriginal = new File(a.getUrl() + nomeOriginal);
        if (fileOriginal.exists()) {
            try {
                au.excluirArquivo(new File(a.getUrl() + a.getNome()));
                a.setNome(nomeOriginal);
                a.setEditado(false);
                anexoServico.update(a);
            } catch (FileNotFoundException ex) {
                Msg.messagemError("Imagem não encontrada");
            }
        }

    }

    public void restaurarAnexo() {
        Anexo a = anexoServico.find(this.idAnexo);
        ArquivoUtilitario au = new ArquivoUtilitario();
        String nomeOriginal = a.getNome().replace("copia_", "");
        File fileOriginal = new File(a.getUrl() + nomeOriginal);
        if (fileOriginal.exists()) {
            try {
                au.excluirArquivo(new File(a.getUrl() + a.getNome()));
                a.setNome(nomeOriginal);
                a.setEditado(false);
                anexoServico.update(a);
            } catch (FileNotFoundException ex) {
                Msg.messagemError("Imagem não encontrada");
            }
        }
    }

    public String visualizarPdf(Anexo a) {
        String[] url = getRequestURL().split(APPLICATION_NAME);
        if (a.getId() != null) {
            return url[0].concat(APPLICATION_NAME) + "show?id=" + a.getId();
        } else {
            return url[0].concat(APPLICATION_NAME) + "show?pdf=" + a.getNome();
        }
    }

    public boolean pdf(Anexo a) {
        String nome = getFileSuffix(a.getNome());

        if (nome != null) {
            return nome.equals("pdf");
        }

        return false;
    }

    public Long getIdAnexo() {
        return idAnexo;
    }

    public void setIdAnexo(Long idAnexo) {
        this.idAnexo = idAnexo;
    }
}
